package com.zhentao.service;

import com.zhentao.dto.AiMessageDTO;
import com.zhentao.dto.ChatHistoryRequest;
import com.zhentao.entity.AiMessage;
import com.zhentao.repository.AiMessageRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * AI消息管理服务
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AiMessageService {
    
    private final AiMessageRepository messageRepository;
    
    /**
     * 保存用户消息
     */
    @Transactional
    public AiMessageDTO saveUserMessage(Integer userId, String conversationId, String content) {
        log.info("保存用户消息，用户ID: {}, 会话ID: {}", userId, conversationId);
        
        AiMessage message = new AiMessage(userId, conversationId, content, "USER");
        
        // 设置消息序号
        long messageCount = messageRepository.countByConversationId(conversationId);
        message.setSequenceNumber((int) (messageCount + 1));
        
        AiMessage saved = messageRepository.save(message);
        return convertToDTO(saved);
    }
    
    /**
     * 保存AI回复消息
     */
    @Transactional
    public AiMessageDTO saveAssistantMessage(Integer userId, String conversationId, String content, 
                                           String aiModel, Long responseTime) {
        log.info("保存AI回复消息，用户ID: {}, 会话ID: {}", userId, conversationId);
        
        AiMessage message = new AiMessage(userId, conversationId, content, aiModel, responseTime);
        
        // 设置消息序号
        long messageCount = messageRepository.countByConversationId(conversationId);
        message.setSequenceNumber((int) (messageCount + 1));
        
        AiMessage saved = messageRepository.save(message);
        return convertToDTO(saved);
    }
    
    /**
     * 获取会话的聊天历史
     */
    public Page<AiMessageDTO> getChatHistory(ChatHistoryRequest request) {
        log.info("获取聊天历史，用户ID: {}, 会话ID: {}, 页码: {}", 
                request.getUserId(), request.getConversationId(), request.getPage());
        
        Sort sort = request.getDescending() ? 
            Sort.by(Sort.Direction.DESC, "timestamp") : 
            Sort.by(Sort.Direction.ASC, "timestamp");
        
        Pageable pageable = PageRequest.of(request.getPage() - 1, request.getSize(), sort);
        
        Page<AiMessage> messages = messageRepository
            .findByUserIdAndConversationIdOrderByTimestampAsc(
                request.getUserId(), 
                request.getConversationId(), 
                pageable
            );
        
        return messages.map(this::convertToDTO);
    }
    
    /**
     * 获取会话的最新消息列表
     */
    public List<AiMessageDTO> getRecentMessages(String conversationId, int limit) {
        log.info("获取最新消息，会话ID: {}, 限制数量: {}", conversationId, limit);
        
        Pageable pageable = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "timestamp"));
        
        Page<AiMessage> messages = messageRepository
            .findByConversationIdOrderByTimestampDesc(conversationId, pageable);
        
        // 返回时需要按时间正序排列
        List<AiMessage> messageList = messages.getContent();
        messageList.sort((m1, m2) -> m1.getTimestamp().compareTo(m2.getTimestamp()));
        
        return messageList.stream()
            .map(this::convertToDTO)
            .collect(Collectors.toList());
    }
    
    /**
     * 获取会话的最后一条消息
     */
    public AiMessageDTO getLastMessage(String conversationId) {
        List<AiMessage> messages = messageRepository
            .findTopByConversationIdOrderByTimestampDesc(conversationId);
        
        if (!messages.isEmpty()) {
            return convertToDTO(messages.get(0));
        }
        
        return null;
    }
    
    /**
     * 统计会话的消息数量
     */
    public long getMessageCount(String conversationId) {
        return messageRepository.countByConversationId(conversationId);
    }
    
    /**
     * 删除会话的所有消息
     */
    @Transactional
    public void deleteMessagesByConversationId(String conversationId) {
        log.info("删除会话消息，会话ID: {}", conversationId);
        messageRepository.deleteByConversationId(conversationId);
    }
    
    /**
     * 删除用户的所有消息
     */
    @Transactional
    public void deleteMessagesByUserId(Integer userId) {
        log.info("删除用户消息，用户ID: {}", userId);
        messageRepository.deleteByUserId(userId);
    }
    
    /**
     * 标记消息为已读
     */
    @Transactional
    public boolean markMessageAsRead(String messageId) {
        return messageRepository.findById(messageId)
            .map(message -> {
                message.markAsRead();
                messageRepository.save(message);
                return true;
            })
            .orElse(false);
    }
    
    /**
     * 获取用户在指定时间范围内的消息统计
     */
    public long getMessageCountByUserAndTimeRange(Integer userId, LocalDateTime startTime, LocalDateTime endTime) {
        return messageRepository.countByUserIdAndTimestampBetween(userId, startTime, endTime);
    }
    
    /**
     * 清理旧消息（用于定时任务）
     */
    @Transactional
    public void cleanupOldMessages(LocalDateTime cutoffTime) {
        log.info("清理旧消息，截止时间: {}", cutoffTime);
        
        List<AiMessage> oldMessages = messageRepository.findMessagesOlderThan(cutoffTime);
        if (!oldMessages.isEmpty()) {
            messageRepository.deleteAll(oldMessages);
            log.info("已清理 {} 条旧消息", oldMessages.size());
        }
    }
    
    /**
     * 转换为DTO
     */
    private AiMessageDTO convertToDTO(AiMessage message) {
        AiMessageDTO dto = new AiMessageDTO();
        dto.setId(message.getId());
        dto.setConversationId(message.getConversationId());
        dto.setContent(message.getContent());
        dto.setMessageType(message.getMessageType());
        dto.setTimestamp(message.getTimestamp());
        dto.setSequenceNumber(message.getSequenceNumber());
        dto.setStatus(message.getStatus());
        dto.setIsSystem(message.getIsSystem());
        dto.setAiModel(message.getAiModel());
        dto.setResponseTime(message.getResponseTime());
        return dto;
    }
}
